import { Logger, LogLevel } from '@nestjs/common'

/**
 * 日志上下文接口
 */
export interface LogContext {
  userId?: string
  sessionId?: string
  requestId?: string
  ip?: string
  userAgent?: string
  method?: string
  url?: string
  statusCode?: number
  responseTime?: number
  [key: string]: any
}

/**
 * 日志工具类
 * 统一处理项目中的日志记录
 */
export class LoggerUtil {
  private static formatMessage(message: string, context?: LogContext): string {
    if (!context) {
      return message
    }

    const contextParts: string[] = []

    if (context.userId) {
      contextParts.push(`userId=${context.userId}`)
    }
    if (context.sessionId) {
      contextParts.push(`sessionId=${context.sessionId}`)
    }
    if (context.requestId) {
      contextParts.push(`requestId=${context.requestId}`)
    }
    if (context.ip) {
      contextParts.push(`ip=${context.ip}`)
    }
    if (context.method && context.url) {
      contextParts.push(`${context.method} ${context.url}`)
    }
    if (context.statusCode) {
      contextParts.push(`status=${context.statusCode}`)
    }
    if (context.responseTime) {
      contextParts.push(`time=${context.responseTime}ms`)
    }

    const contextStr = contextParts.length > 0 ? `[${contextParts.join(', ')}]` : ''
    return `${message} ${contextStr}`.trim()
  }

  /**
   * 记录信息日志
   * @param logger Logger实例
   * @param message 消息
   * @param context 上下文
   */
  static info(logger: Logger, message: string, context?: LogContext): void {
    logger.log(this.formatMessage(message, context))
  }

  /**
   * 记录错误日志
   * @param logger Logger实例
   * @param message 消息
   * @param error 错误对象
   * @param context 上下文
   */
  static error(logger: Logger, message: string, error?: Error | string, context?: LogContext): void {
    const formattedMessage = this.formatMessage(message, context)

    if (error instanceof Error) {
      logger.error(formattedMessage, error.stack)
    } else if (typeof error === 'string') {
      logger.error(`${formattedMessage}: ${error}`)
    } else {
      logger.error(formattedMessage)
    }
  }

  /**
   * 记录警告日志
   * @param logger Logger实例
   * @param message 消息
   * @param context 上下文
   */
  static warn(logger: Logger, message: string, context?: LogContext): void {
    logger.warn(this.formatMessage(message, context))
  }

  /**
   * 记录调试日志
   * @param logger Logger实例
   * @param message 消息
   * @param context 上下文
   */
  static debug(logger: Logger, message: string, context?: LogContext): void {
    logger.debug(this.formatMessage(message, context))
  }

  /**
   * 记录详细日志
   * @param logger Logger实例
   * @param message 消息
   * @param context 上下文
   */
  static verbose(logger: Logger, message: string, context?: LogContext): void {
    logger.verbose(this.formatMessage(message, context))
  }

  /**
   * 记录用户操作日志
   * @param logger Logger实例
   * @param action 操作类型
   * @param resource 资源
   * @param context 上下文
   */
  static userAction(logger: Logger, action: string, resource: string, context?: LogContext): void {
    const message = `用户操作: ${action} ${resource}`
    this.info(logger, message, context)
  }

  /**
   * 记录API请求日志
   * @param logger Logger实例
   * @param method HTTP方法
   * @param url 请求URL
   * @param statusCode 状态码
   * @param responseTime 响应时间
   * @param context 上下文
   */
  static apiRequest(
    logger: Logger,
    method: string,
    url: string,
    statusCode: number,
    responseTime: number,
    context?: LogContext
  ): void {
    const message = 'API请求'
    const fullContext: LogContext = {
      ...context,
      method,
      url,
      statusCode,
      responseTime
    }
    this.info(logger, message, fullContext)
  }

  /**
   * 记录数据库操作日志
   * @param logger Logger实例
   * @param operation 操作类型
   * @param table 表名
   * @param recordId 记录ID
   * @param context 上下文
   */
  static dbOperation(logger: Logger, operation: string, table: string, recordId?: string, context?: LogContext): void {
    const message = `数据库操作: ${operation} ${table}${recordId ? ` (ID: ${recordId})` : ''}`
    this.info(logger, message, context)
  }

  /**
   * 记录认证相关日志
   * @param logger Logger实例
   * @param event 事件类型
   * @param username 用户名
   * @param success 是否成功
   * @param context 上下文
   */
  static authEvent(logger: Logger, event: string, username: string, success: boolean, context?: LogContext): void {
    const message = `认证事件: ${event} - 用户: ${username} - ${success ? '成功' : '失败'}`
    if (success) {
      this.info(logger, message, context)
    } else {
      this.warn(logger, message, context)
    }
  }

  /**
   * 记录文件操作日志
   * @param logger Logger实例
   * @param operation 操作类型
   * @param filename 文件名
   * @param size 文件大小
   * @param context 上下文
   */
  static fileOperation(logger: Logger, operation: string, filename: string, size?: number, context?: LogContext): void {
    const message = `文件操作: ${operation} - ${filename}${size ? ` (${size} bytes)` : ''}`
    this.info(logger, message, context)
  }

  /**
   * 记录性能指标日志
   * @param logger Logger实例
   * @param metric 指标名称
   * @param value 指标值
   * @param unit 单位
   * @param context 上下文
   */
  static performance(logger: Logger, metric: string, value: number, unit: string = 'ms', context?: LogContext): void {
    const message = `性能指标: ${metric} = ${value}${unit}`
    this.info(logger, message, context)
  }
}
